﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nova.Parsing.GoldParser.Semantic;

namespace Nova.Parsing.Tokens
{
    public abstract class ValueToken : NovaToken
    {
        private string m_Value;

        protected ValueToken(string value)
        {
            m_Value = value;
        }

        public abstract object Value { get; }

        public string RawValue { get { return m_Value; } }

        public override string ToString()
        {
            return Value.ToString();
        }
    }

    [Terminal("Vector")]
    public sealed class VectorLiteral : ValueToken
    {
        private float[] m_VectorArray;

        public VectorLiteral(string value)
            : base(value)
        {
            // TODO: Parse the streing value into a real vector
        }

        public override object Value
        {
            get { return m_VectorArray; }
        }
    }

    [Terminal("Integer")]
    public sealed class IntegerLiteral : ValueToken
    {
        private int m_Value;

        public IntegerLiteral(string value)
            : base(value)
        {
            m_Value = int.Parse(value, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.CurrentCulture);
        }

        public override object Value
        {
            get { return m_Value; }
        }
    }

    [Terminal("Float")]
    public sealed class FloatLiteral : ValueToken
    {
        private float m_Value;

        public FloatLiteral(string value)
            : base(value)
        {
            m_Value = float.Parse(value, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.CurrentCulture);
        }

        public override object Value
        {
            get { throw new NotImplementedException(); }
        }
    }

    [Terminal("StringLiteral")]
    public sealed class StringLiteral : ValueToken
    {
        public StringLiteral(string value)
            : base(value)
        {
        }

        public override object Value
        {
            get { return RawValue; }
        }
    }

    [Terminal("Double")]
    public sealed class DoubleLiteral : ValueToken
    {
        private double m_Value;

        public DoubleLiteral(string value)
            : base(value)
        {
            m_Value = double.Parse(value, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.CurrentCulture);
        }

        public override object Value
        {
            get { return m_Value; }
        }
    }

    [Terminal("Char")]
    public sealed class CharLiteral : ValueToken
    {
        private char m_Value;

        public CharLiteral(string value)
            : base(value)
        {
            m_Value = value.ToCharArray(0, 1)[0];
        }

        public override object Value
        {
            get { return m_Value; }
        }
    }

    [Terminal("HexString")]
    public sealed class HexLiteral : ValueToken
    {
        private int m_Value;

        public HexLiteral(string value)
            : base(value)
        {
            m_Value = Convert.ToInt32(value.Substring(2, value.Length - 2), 16);
        }

        public override object Value
        {
            get { return m_Value; }
        }
    }

    [Terminal("Identifier")]
    public sealed class Identifier : ValueToken
    {
        private string m_IdentiferName;

        public Identifier(string value)
            : base(value)
        {
            m_IdentiferName = value;
        }

        public override object Value
        {
            get { return m_IdentiferName; }
        }

        public override string ToString()
        {
            return m_IdentiferName;
        }
    }

    [Terminal("true")]
    public sealed class TrueValue :  ValueToken
    {
        public TrueValue(string value)
            : base(value)
        {
        }

        public override object Value
        {
            get { return true; }
        }
    }

    [Terminal("false")]
    public sealed class FalseValue : ValueToken
    {
        public FalseValue(string value)
            : base(value)
        {
        }

        public override object Value
        {
            get { return false; }
        }
    }
}
